const PROMISE_STATUS_PENDING = "pending";
const PROMISE_STATUS_FULFILLED = "fulfilled";
const PROMISE_STATUS_REJECTED = "rejected";

const execFunctionWithCatchError = (excuFn, value, resolve, reject) => {
  try {
    const result = excuFn(value);
    resolve(result);
  } catch (error) {
    reject(error);
  }
};

class MyPromise {
  constructor(executor) {
    this.status = PROMISE_STATUS_PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.fulfilledFns = [];
    this.rejectedFns = [];
    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          if (this.status !== PROMISE_STATUS_PENDING) return;
          this.status = PROMISE_STATUS_FULFILLED;
          this.value = value;
          this.fulfilledFns.forEach((fn) => {
            fn();
          });
        });
      }
    };

    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          if (this.status !== PROMISE_STATUS_PENDING) return;
          this.status = PROMISE_STATUS_REJECTED;
          this.reason = reason;
          this.rejectedFns.forEach((fn) => {
            fn();
          });
        });
      }
    };
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(fulfilled, rejected) {
    return new MyPromise((resolve, reject) => {
      if (this.status === PROMISE_STATUS_FULFILLED && fulfilled) {
        execFunctionWithCatchError(fulfilled, this.value, resolve, reject);
      }
      if (this.status === PROMISE_STATUS_REJECTED && rejected) {
        execFunctionWithCatchError(rejected, this.reason, resolve, reject);
      }
      if (this.status === PROMISE_STATUS_PENDING) {
        if (fulfilled)
          this.fulfilledFns.push(() => {
            execFunctionWithCatchError(fulfilled, this.value, resolve, reject);
          });
        if (rejected)
          this.rejectedFns.push(() => {
            execFunctionWithCatchError(rejected, this.reason, resolve, reject);
          });
      }
    });
  }
}

const promise = new MyPromise((resolve, reject) => {
  console.log("状态pending");
  // resolve(1111); // resolved/fulfilled
  reject(2222);
  // throw new Error("executor error message");
});

// 调用then方法多次调用(链式调用)
promise
  .then(
    (res) => {
      console.log("res1:", res);
      return "aaaa";
      // throw new Error("err message");
    },
    (err) => {
      console.log("err1:", err);
      // return "bbbbb";
      throw new Error("err message");
    }
  )
  .then(
    (res) => {
      console.log("res2:", res);
    },
    (err) => {
      console.log("err2:", err);
    }
  );
